/*  This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or (at
    your option) any later version.
    For more details, see the GNU Lesser General Public License (www.fsf.org
    or the COPYING file somewhere in the package)
 */

#ifndef OSGI_CGUARD_HH
#define OSGI_CGUARD_HH

#include "OSGi.hh"

/*! @file OSGi/CGuard.hh
    @brief Class OSGi::CGuard header.
    @author @ref Guillaume_Terrissol
    @date 11th December 2009 - 26th May 2013
    @note This file is distributed under the LGPL license.
    Refer to the file COPYING (or http://www.fsf.org) for more information.
 */

#include <functional>

namespace OSGi
{
//------------------------------------------------------------------------------
//                                    C RAII
//------------------------------------------------------------------------------

    /*! @brief RAII for C resources.
        @version 0.75

        Manual memory management often being an annoyance with exception
        handling, I created this class to encapsulate resources allocated by C
        functions, and their release functions at the same time (RAII forever).
    */
    template<class TC>
    class CGuard
    {
    public:
        //! @name Types
        //@{
        using Free = std::function<void (TC*)>;     //!< Ressource freer.
        //@}
        //! @name Constructors & destructor
        //@{
                    CGuard();                       //!< Default constructor.
                    CGuard(TC* pRes, Free pFree);   //!< Constructor.
                    CGuard(CGuard&& pThat);         //!< Move constructeur.
        CGuard&     operator=(CGuard&& pThat);      //!< Move assignment operator.
                    ~CGuard();                      //!< Destructor.
        void        reset();                        //!< Reset.
        //@}
        //! @name Access
        //@{
        const TC*   operator->() const;             //!< [constant] Arrow operator.
        TC*         operator->();                   //!< Arrow operator.
        const TC*   get() const;                    //!< [constant] Direct access.
        TC*         get();                          //!< Direct access.
        //@}

    private:
        //! @name Attributes
        //@{
        Free    mFree;                              //!< Resource freer.
        TC*     mResource;                          //!< Acquired resource.
        //@}
        //! @name Special
        //@{
 static void    nullFree(TC*);                      //!< No-op free.
        //@}
    };
}

#include "CGuard.inl"

#endif  // OSGI_CGUARD_HH
